/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package percussiongenerator.gui;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Collection;
import java.util.HashMap;
import javax.sound.midi.Instrument;
import javax.swing.BoxLayout;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JPanel;
import javax.swing.MutableComboBoxModel;
import org.jfonia.connect5.basics.BasicValueNode;
import org.jfonia.connect5.basics.MutableValueNode;
import org.jfonia.connect5.basics.Observer;
import percussiongenerator.commands.ChangeInstrument;
import percussiongenerator.commands.CommandHistory;
import percussiongenerator.sound.DrumkitHelp;
import percussiongenerator.sound.SimpleInstrument;

/**
 * This panel is used to select an instrument for a Track
 * The panel is connected by a Track with a Equal relation between the
 * selectedInstrumentNode and the Track.instrumentNode.
 * The relation is made in the constructor of TrackOptionsPanel
 * @author Jannes Plyson
 */
public class ChooseInstrumentPanel extends JPanel implements Observer{
    private MutableValueNode<SimpleInstrument> selectedInstrumentNode;
    private final JComboBox comboBoxInstrument;
    private final JComboBox comboBoxPercussion;
    private HashMap<String,Instrument> instrumentList;
    private boolean changeFromNotify;

    public ChooseInstrumentPanel(Instrument[] instruments){
        selectedInstrumentNode = new BasicValueNode<SimpleInstrument>(null);
        selectedInstrumentNode.addObserver(this);
        instrumentList = new HashMap<String, Instrument>();
        this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
        MutableComboBoxModel modelInstruments = new DefaultComboBoxModel();
        for(int i = 0; i < instruments.length; i++){
            if(instruments[i].toString().contains("Drumkit:")){
                this.instrumentList.put("Drumkit: "+instruments[i].getName(), instruments[i]);
                modelInstruments.addElement("Drumkit: "+instruments[i].getName());
            }else{
                this.instrumentList.put(instruments[i].getName(), instruments[i]);
                modelInstruments.addElement(instruments[i].getName());
            }
        }
        MutableComboBoxModel modelPercussion = new DefaultComboBoxModel();
        Collection<String> percussionInstruments = DrumkitHelp.getNames();
        for(String name : percussionInstruments){
            modelPercussion.addElement(name);
        }
        comboBoxInstrument = new JComboBox(modelInstruments);
        comboBoxPercussion = new JComboBox(modelPercussion);
        this.add(comboBoxInstrument);
        comboBoxInstrument.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {                
                JComboBox cb = (JComboBox)e.getSource();
                String string = (String)cb.getSelectedItem();
                if(string.contains("Drumkit:")){
                    comboBoxPercussion.setEnabled(true);
                }else{
                    comboBoxPercussion.setEnabled(false);
                    if(!changeFromNotify){
                        CommandHistory.addCommandAndExecute(new ChangeInstrument(selectedInstrumentNode, new SimpleInstrument(instrumentList.get((String)cb.getSelectedItem()))));
                    }                    
                }
            }
        });
        comboBoxInstrument.setMaximumSize(comboBoxInstrument.getPreferredSize());
        this.add(comboBoxPercussion);
        comboBoxPercussion.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {                
                JComboBox cb = (JComboBox)e.getSource();
                String name = (String)cb.getSelectedItem();
                int number = DrumkitHelp.getPitch(name);
                Instrument instrument = instrumentList.get((String)comboBoxInstrument.getSelectedItem());                
                if(!changeFromNotify){
                    CommandHistory.addCommandAndExecute(new ChangeInstrument(selectedInstrumentNode, new SimpleInstrument(instrument,number)));
                }
            }
        });
        comboBoxPercussion.setMaximumSize(comboBoxPercussion.getPreferredSize());
        changeFromNotify = false;
    }

    public SimpleInstrument getSelectedInstrument(){
        return selectedInstrumentNode.getValue();
    }

    public MutableValueNode<SimpleInstrument> getSelectedInstrumentNode(){
        return selectedInstrumentNode;
    }

    /**
     * When the instrument of the track is changed the comboboxes need to be
     * updated.
     * @param source is selectedInstrumentNode
     */
    public void onNotify(Object source) {
        SimpleInstrument instrument = selectedInstrumentNode.getValue();
        changeFromNotify = true;
        if(instrument.drumkitInstrument != -1){
            comboBoxInstrument.setSelectedItem("Drumkit: " + instrument.instrument.getName());
            comboBoxPercussion.setEnabled(true);
            comboBoxPercussion.setSelectedItem(DrumkitHelp.getName(instrument.drumkitInstrument));            
        }else{
            comboBoxInstrument.setSelectedItem(instrument.instrument.getName());
            comboBoxPercussion.setEnabled(false);
        }
        changeFromNotify = false;
    }
}
